home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / vgl20.zip / VGLKEY.C < prev    next >
C/C++ Source or Header  |  1993-05-14  |  6KB  |  136 lines

  1. /*****************************************************************************
  2.  VGLKEY.C
  3.  
  4.  This module supplies two functions.  The first turns on an int 9 handler
  5.  that allows you to test for multiple keys being held down, very useful in
  6.  a game situation!  The second function simply restores the original int 9
  7.  handler.
  8.  
  9.  Mark
  10.  morley@camosun.bc.ca
  11. *****************************************************************************/
  12.  
  13. #include <dos.h>
  14. #include "vgl.h"
  15.  
  16. struct KEYMAP                           /* This holds a list of key scan   */
  17. {                                       /* codes that we want to trap.     */
  18.    unsigned char downcode;              /* Code when key is pressed        */
  19.    unsigned char upcode;                /* Code when key is released       */
  20. }
  21. Keys[VGL_NUMKEYS] =                     /* Add keys here!!!                */
  22. {
  23.    VGL_UPARROW,
  24.    VGL_DOWNARROW,
  25.    VGL_LEFTARROW,
  26.    VGL_RIGHTARROW
  27. };
  28.  
  29. char vglKeyStatus[VGL_NUMKEYS];         /* An array to hold key status     */
  30.                                         /* info.  One byte per key defined */
  31.                                         /* above.  If a key is currently   */
  32.                                         /* being held down, its byte in    */
  33.                                         /* this list will be decimal 1,    */
  34.                                         /* otherwise it will be a 0.  The  */
  35.                                         /* first key in the list above     */
  36.                                         /* maps to vglKeyStatus[0], the    */
  37.                                         /* second to vglKeyStatus[1], etc  */
  38.  
  39. static void interrupt (*oldint1b)();
  40. static void interrupt (*oldint23)();
  41. static void interrupt (*oldint9)();     /* Old int 9 handler               */
  42.  
  43. static int  NumLock;                    /* Used to remember if NumLock was */
  44.                                         /* active when we started.         */
  45.  
  46.                                         /* Pointer to shift status area    */
  47. static unsigned char far* kbdata = (unsigned char far*) MK_FP( 0x40, 0x17 );
  48.  
  49.                                         /* Macro to acknowledge a keystroke*/
  50. #define ACKKEY  al = ah = inportb( 0x61 ); \
  51.                 al |= 0x80;                \
  52.                 outportb( 0x61, al );      \
  53.                 outportb( 0x61, ah );      \
  54.                 outportb( 0x20, 0x20 )
  55.  
  56. void interrupt int1b( void ) {}
  57. void interrupt int23( void ) {}
  58.  
  59. /*****************************************************************************
  60.   The int 9 handler.  This routine fires everytime a key is pressed or
  61.   released on the keyboard.  Since each key generates a unique (more or less)
  62.   scan code both when it's pressed, and a different one when it's released,
  63.   we can actually have multiple keys being held down simultaneously.
  64.  
  65.   This routine simple loops through the list you define above, checking the
  66.   current scan code against the up and down codes.  If it matches one, then
  67.   it sets or resets the appropriate byte in the vglKeyStatus[] array.
  68. *****************************************************************************/
  69. void interrupt int9( void )
  70. {
  71.    register i;
  72.    unsigned char al, ah, c;
  73.  
  74.    c = inportb( 0x60 );                 /* Get the scan code               */
  75.    for( i = 0; i < VGL_NUMKEYS; i++ )   /* Loop through the table          */
  76.    {
  77.       if( c == Keys[i].downcode )       /* Is it a downcode?               */
  78.       {
  79.          ACKKEY;                        /* Acknowledge the keystroke       */
  80.          vglKeyStatus[i] = 1;           /* Set the status byte to 1        */
  81.          break;                         /* We're done!                     */
  82.       }
  83.       if( c == Keys[i].upcode )         /* Is it an upcode?                */
  84.       {
  85.          ACKKEY;                        /* Acknowledge the keystroke       */
  86.          vglKeyStatus[i] = 0;           /* Reset the status byte to 0      */
  87.          break;                         /* We're done!                     */
  88.       }
  89.    }
  90.    if( i == VGL_NUMKEYS )               /* Otherwise, we call the original */
  91.       _chain_intr( oldint9 );           /* int 9 handler                   */
  92. }
  93.  
  94. /*****************************************************************************
  95.   Called to start the trapping of keys.  The current status of the NumLock
  96.   key is preserved, then NumLock is turned off.  Don't forget to call
  97.   vglReleaseKeys() before your program exits!
  98. *****************************************************************************/
  99. vglTrapKeys()
  100. {
  101.    int i;
  102.  
  103.    for( i = 0; i < VGL_NUMKEYS; i++ )   /* Initialize the status bytes      */
  104.       vglKeyStatus[i] = 0;
  105.  
  106.    NumLock = (*kbdata & 32) == 32;      /* Save the current numlock status  */
  107.  
  108.    *kbdata &= (255-32);                 /* Turn off numlock                 */
  109.  
  110.    oldint9 = getvect( 0x09 );           /* Save the current int 9 handler   */
  111.    oldint1b = getvect( 0x1b );
  112.    oldint23 = getvect( 0x23 );
  113.  
  114.    setvect( 0x09, int9 );               /* Install out int 9 handler        */
  115.    setvect( 0x1b, int1b );
  116.    setvect( 0x23, int23 );
  117.    return;
  118. }
  119.  
  120. /*****************************************************************************
  121.   Stops the trapping of keys.  NumLock is restored to its previous value.
  122.   IMPORTANT!!!  If you previously called vglTrapKeys(), you **MUST** call
  123.   this routine before exiting your program or evil things may happen!
  124. *****************************************************************************/
  125. vglReleaseKeys()
  126. {
  127.    setvect( 0x09, oldint9 );            /* Restore the old int 9 handler    */
  128.    setvect( 0x1b, oldint1b );
  129.    setvect( 0x23, oldint23 );
  130.  
  131.    if( NumLock )                        /* Restore the numlock status       */
  132.       *kbdata |= 32;
  133.    return;
  134. }
  135.  
  136.